package com.allwees.bs.module.ops.rest;

import com.allwees.bs.module.core.annotation.PrintLog;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.allwees.bs.core.model.ops.AdsModel;
import com.allwees.bs.core.model.ops.constant.AdPositionEnum;
import com.allwees.bs.core.model.ops.event.AdUpdatedEvent;
import com.allwees.bs.core.modelbase.vo.R;
import com.allwees.bs.module.ops.req.AdDTO;
import com.allwees.bs.module.ops.req.AdEditDTO;
import com.allwees.bs.module.ops.req.AdQueryDTO;
import com.allwees.bs.module.ops.service.AdsService;
import me.zhengjie.utils.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author Daniel
 * @Version 1.0.0
 * @Description 广告管理后台
 * @CreateTime 2020/10/16 13:31
 */
@PrintLog
@RestController
@RequestMapping("/backstage/api/ads")
public class AdvertisementApi {

    @Resource
    private AdsService adsService;

    @Resource
    protected ApplicationContext context;

    @GetMapping("/pos")
    public R positions() {
        Map<Integer, String> positions =
                Arrays.stream(AdPositionEnum.values())
                        .collect(Collectors.toMap(AdPositionEnum::getCode, AdPositionEnum::getName));
        return R.ok(positions);
    }

    @GetMapping("/page")
    public R page(AdQueryDTO dto) {
        LambdaQueryChainWrapper<AdsModel> lambdaQuery = adsService.lambdaQuery();
        lambdaQuery.eq(dto.getStatus() != null, AdsModel::getStatus, dto.getStatus());
        lambdaQuery.eq(dto.getPlatform() != null,AdsModel::getPlatform,dto.getPlatform());
        lambdaQuery.likeRight(StringUtils.isNotBlank(dto.getName()), AdsModel::getName, dto.getName());
        if (dto.getPosition() != null) {
            lambdaQuery.eq(AdsModel::getPosition, dto.getPosition());
        }

        lambdaQuery.ge(dto.getCreatedFrom() != null, AdsModel::getCreatedAt, dto.getCreatedFrom());
        lambdaQuery.lt(dto.getCreatedTo() != null, AdsModel::getCreatedAt, dto.getCreatedTo());
        lambdaQuery.orderByDesc(AdsModel::getId);
        return R.ok(lambdaQuery.page(dto.toPage()));
    }

    @Transactional
    @PostMapping
    public R create(@Validated(AdDTO.Add.class) @RequestBody AdEditDTO dto) {
        AdPositionEnum position = dto.getPosition();
        if(position == AdPositionEnum.HOME_POPUPS ||
                position == AdPositionEnum.CATETORY_BANNER ||
                position == AdPositionEnum.PRODUCT_LIST){
            Assert.isTrue(dto.getParam() != null,"缺少param参数");
        }
        AdsModel entity = dto.toEntity();
        if (adsService.save(entity)) {
            context.publishEvent(new AdUpdatedEvent(entity.getId()));
        }
        return R.ok();
    }

    @Transactional
    @PutMapping
    public R update(@Validated(AdDTO.Edit.class) @RequestBody AdEditDTO dto) {
        AdsModel entity = dto.toEntity();
        if (adsService.updateById(entity)) {
            context.publishEvent(new AdUpdatedEvent(entity.getId()));
        }
        return R.ok();
    }

    @Transactional
    @PutMapping("/status")
    public R enable(@Validated(AdDTO.Edit.class) @RequestBody AdEditDTO dto) {
        LambdaUpdateChainWrapper<AdsModel> wrapper = adsService.lambdaUpdate();
        wrapper.eq(AdsModel::getId, dto.getId());
        wrapper.eq(AdsModel::getStatus,1 ^ dto.getStatus());
        wrapper.set(AdsModel::getStatus, dto.getStatus());
        wrapper.set(AdsModel::getUpdatedAt, new Date());
        boolean updated = wrapper.update();
        if (updated) {
            context.publishEvent(new AdUpdatedEvent(dto.getId()));
        }
        return R.ok();
    }

    @Transactional
    @DeleteMapping("/{id}")
    public R delete(@PathVariable("id") Integer id) {
        if (adsService.removeById(id)) {
            context.publishEvent(new AdUpdatedEvent(id));
        }
        return R.ok();
    }
}
